/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-08-03     Lenovo       the first version
 */
#include "stdlib.h"
#include "thaisenChargModule.h"
//#include "thaisenGuoWang.h"
#include "thaisenPowerControl.h"
#include "app_data_info_interface.h"
#define DBG_TAG "thaisenChargModule"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#define THAISEN_MODULE_DEBUG_ENABLE_OUTPUTA        (1 <<0)
#define THAISEN_MODULE_DEBUG_ENABLE_OUTPUTB        (1 <<1)
#define THAISEN_MODULE_DEBUG_DISABLE_OUTPUTA       (1 <<2)
#define THAISEN_MODULE_DEBUG_DISABLE_OUTPUTB       (1 <<3)

#define VALID_FAULT_NUMBER                      3             /* 有效模块数量 */
#define INPUT_OVERVOLT_FAULT_COUNT_INDEX        0             /* 输入过压故障 */
#define INPUT_UNDERVOLT_FAULT_COUNT_INDEX       1             /* 输入欠压故障 */
//#define OVERTEMP_FAULT_COUNT_INDEX              2             /* 过温故障 */
#define OVERCURR_FAULT_COUNT_INDEX              2             /* 过流故障 */
//#define OUTPUT_OVERVOLT_FAULT_COUNT_INDEX       4             /* 输出过压故障 */
//#define OUTPUT_UNDERVOLT_FAULT_COUNT_INDEX      5             /* 输出欠压故障 */
//#define MODULE_FAULT_COUNT_INDEX                6             /* 模块故障 */
static uint16_t liquid_count;
struct
{
    uint16_t maxVolt;
    uint16_t minVolt;
    uint16_t maxCurr;
    uint16_t minCurr;
    uint16_t maxChargVolt;
    uint16_t maxChargCurrTotal;
    uint16_t maxChargCurrGroup[THAISEN_MODULE_GROUP_NUM];
}thaisenChargModuleInfo;

struct
{
   uint16_t  groupNum;
   uint16_t  groupChargNum[THAISEN_MODULE_GROUP_NUM];
   uint16_t  runNum;
   uint8_t   normalNum;

}thaisenChargModuleRunInfo[THAISEN_MODULE_GROUP_NUM];//充电模块信息

struct
{
    uint16_t setup_voltage[THAISEN_MODULE_GROUP_NUM];     /* 设定电压 */
    uint16_t setup_current[THAISEN_MODULE_GROUP_NUM];     /* 设定电流 */
    uint8_t enable_state;                                 /* 启用状态 */
}thaisenModuleDebugConfig;

void thaisenChangeModuleStatus(thaisenModuleStatusEn status,uint8_t gunNum);
uint8_t thaisenModuleGetStatus(uint8_t gunNum);

uint8_t thaisenModuleStatus[THAISEN_MODULE_GROUP_NUM] = {thaisenModuleIdle};
thaisenModuleSt* ModuleInfo[THAISEN_MODULE_GROUP_NUM];
thasienModuleSetStruct* ModuleSetInfo;
thasienPowerControlSetStruct* PowerInfoSetInfo;

static thaisenModuleFaultInfoStruct ModuleFaultInfo[THAISEN_MODULE_SIGNALGROUP_NUMMAX];
//static thaisenModuleFaultInfoStruct ModuleFaultInfoLast[THAISEN_MODULE_GROUP_NUM][THAISEN_MODULE_SIGNALGROUP_NUMMAX];
static thaisenModuleVoltCurrStruct ModuleVoltCurrInfo[THAISEN_MODULE_SIGNALGROUP_NUMMAX];
static uint16_t fault_detect_delay[THAISEN_MODULE_GROUP_NUM][VALID_FAULT_NUMBER];

void thaisenSetModuleGroupNum(uint16_t groupNum,uint8_t gunNum)
{
    if(groupNum > THAISEN_MODULE_GROUP_NUM)
        return ;

    thaisenChargModuleRunInfo[gunNum].groupNum = groupNum;
}//设置充电模块组数//

uint16_t thaisenGetModuleGroupNum(uint8_t gunNum)
{
    return thaisenChargModuleRunInfo[gunNum].groupNum;
}//获取充电模块组数


void thaisenSetModuleNum(uint16_t num,uint8_t gunNum)
{
    if(num == 0)
        return ;

    thaisenChargModuleRunInfo[gunNum].groupChargNum[gunNum] = num;
}
//设置组内个数
uint16_t thaisenGetModuleNum(uint8_t gunNum)
{
  return thaisenChargModuleRunInfo[gunNum].groupChargNum[gunNum];
}
//获取组内个数
void thaisenSetModuleRunNum(uint16_t num,uint8_t gunNum)
{
    thaisenChargModuleRunInfo[gunNum].runNum = num;
}


uint16_t thaisenGetModuleGunNum(uint8_t gunNum)
{
   return thaisenChargModuleRunInfo[gunNum].runNum;
}



void thaisenSetModuleMaxVolt(uint16_t volt)
{
    thaisenChargModuleInfo.maxVolt = volt;
}

uint16_t thaisenGetModuleMaxVolt(void)
{
    return  thaisenChargModuleInfo.maxVolt;
}

void thaisenSetModuleMinVolt(uint16_t volt)
{
    thaisenChargModuleInfo.minVolt = volt;
}

uint16_t thaisenGetModuleMinVolt(void)
{
    return thaisenChargModuleInfo.minVolt;
}

void thaisenSetModuleMaxCurr(uint16_t curr)
{
    thaisenChargModuleInfo.maxCurr = curr;
}

uint16_t thaisenGetModuleMaxCurr(void)
{
    return thaisenChargModuleInfo.maxCurr;
}

void thaisenSetModuleMinCurr(uint16_t curr)
{
    thaisenChargModuleInfo.minCurr = curr;
}

uint16_t thaisenGetModuleMinCurr(void)
{
    return thaisenChargModuleInfo.minCurr;
}

void thaisenSetModuleMaxChargVolt(uint16_t volt)
{
    thaisenChargModuleInfo.maxChargVolt = volt;
}

uint16_t thaisenGetModuleMaxChargVolt(void)
{
    return thaisenChargModuleInfo.maxChargVolt;
}

void thaisenSetModuleMaxChargCurr(uint16_t curr)
{
    thaisenChargModuleInfo.maxChargCurrTotal = curr;
}

uint16_t thaisenGetModuleMaxChargCurr(void)
{
    return thaisenChargModuleInfo.maxChargCurrTotal;
}

void thaisenSetModuleMaxChargCurrGroup(uint8_t groupNum, uint16_t curr)
{
    if(groupNum >= THAISEN_MODULE_GROUP_NUM){
        return;
    }
    thaisenChargModuleInfo.maxChargCurrGroup[groupNum] = curr;
}

uint16_t thaisenGetModuleMaxChargCurrGroup(uint8_t groupNum)
{
    if(groupNum >= THAISEN_MODULE_GROUP_NUM){
        return 0;
    }
    return thaisenChargModuleInfo.maxChargCurrGroup[groupNum];
}

/**       模块调试部分:设置模块电压输出设定值             */
void thaisenSetModuleSetupVolt(uint16_t setupVolt, uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return;
    }
    thaisenModuleDebugConfig.setup_voltage[gunNum] = setupVolt;
}
/**       模块调试部分:设置模块电流输出设定值             */
void thaisenSetModuleSetupCurr(uint16_t setupCurr, uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return;
    }
    thaisenModuleDebugConfig.setup_current[gunNum] = setupCurr;
}
/**       模块调试部分:获取模块电压输出设定值             */
uint16_t thaisenGetModuleSetupVolt(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return 0;
    }
    return thaisenModuleDebugConfig.setup_voltage[gunNum];
}
/**       模块调试部分:获取模块电流输出设定值             */
uint16_t thaisenGetModuleSetupCurr(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return 0;
    }
    return thaisenModuleDebugConfig.setup_current[gunNum];
}
/**       模块调试部分:启动使能             */
void thaisenSetModuleDebugEnableOutput(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return;
    }
    thaisenModuleDebugConfig.enable_state |= (1 <<gunNum);
    rt_kprintf("%d",thaisenModuleDebugConfig.enable_state);
}
/**       模块调试部分:启动失能             */
void thaisenClearModuleDebugEnableOutput(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return;
    }
    thaisenModuleDebugConfig.enable_state &= (~(1 <<gunNum));
}
/**       模块调试部分:停止使能             */
void thaisenSetModuleDebugDisableOutput(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return;
    }
    thaisenModuleDebugConfig.enable_state |= (1 <<(gunNum + THAISEN_MODULE_GROUP_NUM));
}
/**       模块调试部分:停止失能             */
void thaisenClearModuleDebugDisableOutput(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return;
    }
    thaisenModuleDebugConfig.enable_state &= (~(1 <<(gunNum + THAISEN_MODULE_GROUP_NUM)));
}

/**       模块调试部分:获取启动使能状态             */
uint8_t thaisenGetModuleDebugEnableOutput(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return 0;
    }
    if(thaisenModuleDebugConfig.enable_state &(1 <<gunNum))
        return 1;
    else
        return 0;
}
/**       模块调试部分:获取停止使能状态             */
uint8_t thaisenGetModuleDebugDisableOutput(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return 0;
    }
    if(thaisenModuleDebugConfig.enable_state &(1 <<(gunNum + THAISEN_MODULE_GROUP_NUM)))
        return 1;
    else
        return 0;
}
/**       设置系统指定枪正常模块数量，就是设置的模块数量，没有判断正不正常             */
static void thaisenSetNormalModuleNum(uint8_t Num, uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return;
    }
    if(Num > THAISEN_MODULE_SIGNALGROUP_NUMMAX)
    {
        Num = THAISEN_MODULE_SIGNALGROUP_NUMMAX;
    }
    thaisenChargModuleRunInfo[gunNum].normalNum = Num;
}
/**       获取系统指定枪正常模块数量               */
uint8_t thaisenGetNormalModuleNum(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return 0;
    }
    return thaisenChargModuleRunInfo[gunNum].normalNum;
}
/**************
 * 获取一把枪运行的模块的故障
 * @param Number
 * @param gunNum
 * @return
 */
thaisenModuleFaultInfoStruct *thaisenGetModuleFaultInfo(uint8_t *Number, uint8_t gunNum)
{
//        rt_kprintf("--3_--%d--\r\n",gunNum);
    extern uint16_t thaisenGetModuleNum(uint8_t gunNum);
    thaisenModuleGeneralFaultStruct* temp;
    uint8_t ValidNum = 0, base = 0, module_num = 0;
    if(gunNum >= THAISEN_MODULE_GROUP_NUM){
        if(Number){
            *Number = 0;
        }
        return NULL;
    }
    base = gunNum *THAISEN_MODULE_SIGNALGROUP_NUMMAX;
    module_num = thaisenGetModuleNum(gunNum);
    for(uint8_t number = 0; number < module_num; number++){
        temp = (thaisenModuleGeneralFaultStruct*)(ModuleInfo[gunNum]->Elect.getModuleState(gunNum, number));
        ModuleFaultInfo[ValidNum].addr = number + base;
        ModuleFaultInfo[ValidNum].state.fault.fault_val = temp->fault.fault_val;
        ModuleFaultInfo[ValidNum].state.warn.warn_val = temp->warn.warn_val;
        ModuleFaultInfo[ValidNum].state.state.state_val = temp->state.state_val;
        ModuleFaultInfo[ValidNum].state.temperature = temp->temperature;
        ValidNum++;
    }
    if(Number){
        *Number = ValidNum;
    }
    return ModuleFaultInfo;
}


/*********
 * 库里面是这个函数通过调用这个函数带，调用每个模块设置电压电流数据
 * @param Number
 * @param gunNum
 * @return
 */
thaisenModuleVoltCurrStruct *thaisenGetModuleVoltCurrInfo(uint8_t *Number, uint8_t gunNum)
{
    extern uint16_t thaisenGetModuleNum(uint8_t gunNum);
    thaisenModuleVoltCurrStruct *temp;
    uint8_t ValidNum = 0, module_num = 0;
    if(gunNum >= THAISEN_MODULE_GROUP_NUM){
        if(Number){
            *Number = 0;
        }
        return NULL;
    }
    module_num = thaisenGetModuleNum(gunNum);
    for(uint8_t number = 0; number < module_num; number++){
        temp = (thaisenModuleVoltCurrStruct *)(ModuleInfo[gunNum]->Elect.getModuleVoltCurr(gunNum, number));
        if(temp == NULL){
        }else{
            ModuleVoltCurrInfo[ValidNum].addr = temp->addr;
            ModuleVoltCurrInfo[ValidNum].current = temp->current;
            ModuleVoltCurrInfo[ValidNum].voltage = temp->voltage;
            ValidNum++;
        }
    }
    if(Number){
        *Number = ValidNum;
    }
    return ModuleVoltCurrInfo;
}

uint32_t thaisenGetModuleOutputVoltage(uint8_t gunNum)
{
    if(gunNum >= THAISEN_MODULE_GROUP_NUM)
    {
        return 0;
    }
    return ModuleInfo[gunNum]->Elect.moduleGetVolt(gunNum);
}

struct rt_messagequeue thaisenModuleMq;
can_msg_buf thaisenModuleMsgPool[200];


int thaisenModuleInit(struct thasienPowerControlSetStruct *powerS)
{
    rt_err_t result;

   /* 初始化消息队列 */
   result = rt_mq_init(&thaisenModuleMq,
                       "mqt",
                       &thaisenModuleMsgPool[0],             /* 内存池指向 msg_pool */
                       sizeof(can_msg_buf),                          /* 每个消息的大小是 1 字节 */
                       sizeof(thaisenModuleMsgPool),        /* 内存池的大小是 msg_pool 的大小 */
                       RT_IPC_FLAG_PRIO);       /* 如果有多个线程等待，优先级大小的方法分配消息 */

   if (result != RT_EOK)
   {
       LOG_E("init message queue failed.\n");
       return -1;
   }

   PowerInfoSetInfo = rt_malloc(sizeof(thasienPowerControlSetStruct));//使用 rt_malloc 函数为它分配内存
	if((PowerInfoSetInfo == NULL)||(powerS ==NULL)) //检查分配内存和传入指针是否为NULL
	{
		LOG_E("rt_malloc thasienPowerControlSetStruct failed.\n");
		return -1;
	}

	memcpy(PowerInfoSetInfo,powerS,sizeof(thasienPowerControlSetStruct));
	LOG_I("teminal_addrA = %d, teminal_addrB = %d,gunNumber = %d.\r\n",PowerInfoSetInfo->teminal_addrA,PowerInfoSetInfo->teminal_addrA,PowerInfoSetInfo->gunNumber);

	if((PowerInfoSetInfo->gunNumber > THAISEN_MODULE_GROUP_NUM) || (PowerInfoSetInfo->gunNumber <= 0))
	    PowerInfoSetInfo->gunNumber = THAISEN_MODULE_GROUP_NUM;//若传入组数大于2，或者小于等于0，默认两组



    for(uint8_t i = 0;i < THAISEN_MODULE_GROUP_NUM;i++)//(PowerInfoSetInfo->moduleGroupNum)
    {
        ModuleInfo[i] = rt_malloc(sizeof(thaisenModuleSt));//为模块信息分配内存
         if(ModuleInfo[i] == NULL)
         {
         	LOG_E("rt_malloc thaisenModuleSt failed.\n");
             return -1;
         }
    }


        for(int i = 0;i < (THAISEN_MODULE_GROUP_NUM);i++)
        {
            ModuleInfo[i]->Elect.moduleInit = thaisen_PowerControl_init;
            ModuleInfo[i]->Elect.moduleOpenClose = thaisen_set_powercontrol_open_close;
            ModuleInfo[i]->Elect.moduleSetVoltCurr = thaisen_set_powercontrol_volt_curr;
            ModuleInfo[i]->Elect.moduleAddress = thaisen_set_powercontrol_address;
            ModuleInfo[i]->Elect.moduleGroup = thaisen_set_powercontrol_group;
            ModuleInfo[i]->Elect.moduleReadVoltCurr = thaisen_read_powercontrol_volt_curr_group;
            ModuleInfo[i]->Elect.moduleGetVolt = thaisen_get_powercontrol_volt;
            ModuleInfo[i]->Elect.chargModuleProcess = thaisen_powercontrol_process;
            ModuleInfo[i]->Elect.moduleReadState = thaisen_read_powercontrol_status_group;
            ModuleInfo[i]->Elect.getModuleState = thaisen_getpowercontrol_state;
            ModuleInfo[i]->Elect.getModuleVoltCurr = thaisen_get_powercontrol_voltage_current;
            ModuleInfo[i]->Elect.moduleHeart = thaisen_send_heartbeat_powercontrol_broadcast;
            ModuleInfo[i]->Elect.set_terminal_status = thaisen_set_terminal_status;
            ModuleInfo[i]->Elect.set_terminal_data = thaisen_set_terminal_data;
        }

	  ModuleInfo[THAISE_MODULE_GROUP_1]->Elect.CC1_Status = thaisen_get_CC1_status;//获取cc1状态
	  ModuleInfo[THAISE_MODULE_GROUP_2]->Elect.CC1_Status = thaisen_get_CC1_statusB;


	for(int i = 0;i < (THAISEN_MODULE_GROUP_NUM);i++)
	{		
	    extern void thaisen_relay_A_on(void);
        extern void thaisen_relay_A_off(void);
        extern void thaisen_relay_B_on(void);
        extern void thaisen_relay_B_off(void);//函数的外部声明

   		ModuleInfo[i]->Elect.parallelZRelayEnable = thaisen_relay_parallel_on_z;//母联正负开关
	    ModuleInfo[i]->Elect.parallelZRelayClose = thaisen_relay_parallel_off_z;
	    ModuleInfo[i]->Elect.parallelFRelayEnable = thaisen_relay_parallel_on_f;
	    ModuleInfo[i]->Elect.parallelFRelayClose = thaisen_relay_parallel_off_f;
        ModuleInfo[i]->Elect.dcRelayEnableA = thaisen_relay_A_on;//直流正负开关
        ModuleInfo[i]->Elect.dcRelayCloseA = thaisen_relay_A_off;
        ModuleInfo[i]->Elect.dcRelayEnableB = thaisen_relay_B_on;
        ModuleInfo[i]->Elect.dcRelayCloseB = thaisen_relay_B_off;
	    ModuleInfo[i]->Elect.AmmeterVolt = thaisen_get_ammeterVolt;//获取电表电压
	}
    return 0;
}

/**********
 * 记录当前充电状态
 * @param gunNum
 */
void thaisenModuleIdleFun(uint8_t gunNum)
{
    thaisenSetModuleRunNum(thaisenGetModuleNum(gunNum),gunNum);//运行模块的数量等于获取的模块数量
    if(thaisenGetModuleDebugEnableOutput(gunNum) == 0){//未使能关机
//        ModuleInfo[gunNum]->Elect.moduleOpenClose(1,gunNum, thaisenModuleGetStatusFun(gunNum), 0x00);
    }
    if(thaisenModuleGetStatusFun(gunNum) == thaisenChargCHM || thaisenModuleGetStatusFun(gunNum) == thaisenChargInsult)//若是在CHM或者绝缘检测阶段
    {
        thaisenChangeModuleStatus(thaisenModuleChargInsult,gunNum);//设置现在的状态
        rt_thread_mdelay(1000);//延时1s返回
        return ;
    }
    else if(thaisenModuleGetStatusFun(gunNum) == thaisenChargCRO || thaisenModuleGetStatusFun(gunNum) == thaisenChargCROAA)
    {
        thaisenChangeModuleStatus(thaisenModuleChargCRO,gunNum);
        return ;
    }
}


void thaisenModuleChargInsultFun(uint8_t gunNum)
{
    static uint16_t cnt[THAISEN_MODULE_GROUP_NUM] ={0,0};


    switch(thaisenModuleGetStatusFun(gunNum))
    {
        case thaisenChargIdle:
            thaisenChangeModuleStatus(thaisenModuleIdle,gunNum);
            break;
        case thaisenChargCHM:
        case thaisenChargInsult:
            if(++cnt[gunNum] > 2)
            {
               cnt[gunNum] = 0;

//               if(thaisenBMS_Add[gunNum]->BHM.MaxAllowVol < 1500)//最高允许电压小于150退出
//               {
//                   break;
//               }

               if(thaisenBMS_Add[gunNum]->BHM.MaxAllowVol < thaisenGetModuleMinVolt() || thaisenBMS_Add[gunNum]->BHM.MaxAllowVol > thaisenGetModuleMaxVolt())//若最高允许电压小于模块的最小电压，大于模块的最大电压
               {
                   ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenGetModuleMinVolt(),500,gunNum, thaisenModuleGetStatusFun(gunNum));//设置模块的电压电流
                   thaisenBMS_Add[gunNum]->BHM.MaxAllowVol = thaisenGetModuleMinVolt();//最高允许电压设置为模块的最小电压
                   ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenGetModuleMinVolt());//开机//电池电压为模块的最小电压
               }
               else
               {
                   ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum]->BHM.MaxAllowVol,500,gunNum, thaisenModuleGetStatusFun(gunNum));//设置电压为最高允许电压，电流5A
                   ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BHM.MaxAllowVol);//电池电压为最高允许电压
               }
            }
            thaisenSetLiquidStart(gunNum);
            liquid_count = 0; //液冷计数置零
           break;
        case thaisenChargInsultFinish:
        case thaisenChargCRM:
        case thaisenChargCTSCML:
            ModuleInfo[gunNum]->Elect.moduleOpenClose(1,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
            break;
        case thaisenChargCST:
        case thaisenChargCSD:
        case thaisenChargStop:
        case thaisenChargWaitGun:
        case thaisenChargFault:
        case thaisenChargingFault:
        case thaisenChargCommonFault:
        case thaisenChargCommonEndFault:
            ModuleInfo[gunNum]->Elect.moduleOpenClose(1,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
            thaisenChangeModuleStatus(thaisenModuleChargStop,gunNum);
            break;

        case thaisenChargCRO:
             cnt[gunNum] = 0;
             thaisenChangeModuleStatus(thaisenModuleChargCRO,gunNum);
             break;
    }
}


void thaisenModuleChargCROFun(uint8_t gunNum)
{
    static uint16_t cnt[THAISEN_MODULE_GROUP_NUM] ={0,0};

    switch(thaisenModuleGetStatusFun(gunNum))
     {
        case thaisenChargIdle:
            thaisenChangeModuleStatus(thaisenModuleIdle,gunNum);
            break;

         case thaisenChargCHM:
         case thaisenChargInsult:
         case thaisenChargInsultFinish:
         case thaisenChargCRM:
         case thaisenChargCTSCML:
         case thaisenChargCST:
         case thaisenChargCSD:
         case thaisenChargStop:
         case thaisenChargWaitGun:
         case thaisenChargFault:
         case thaisenChargingFault:
         case thaisenChargCommonFault:
         case thaisenChargCommonEndFault:
             ModuleInfo[gunNum]->Elect.moduleOpenClose(1,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
             thaisenChangeModuleStatus(thaisenModuleChargStop,gunNum);
             break;

         case thaisenChargCRO:
         case thaisenChargCROAA:
             thaisenBMS_Add[gunNum]->BHM.MaxAllowVol = thaisenGetModuleMaxVolt();
             if(++cnt[gunNum] > 2)
             {
                cnt[gunNum] = 0;
                ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum]->BCP.BatVolt,1000,gunNum, thaisenModuleGetStatusFun(gunNum));
                ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
             }
             break;
         case thaisenChargCCS:
             cnt[gunNum] = 0;
             thaisenChangeModuleStatus(thaisenModuleChargCCS,gunNum);
             break;
     }
}


void thaisenModuleChargCCSFun(uint8_t gunNum)
{
     static uint16_t cnt[THAISEN_MODULE_GROUP_NUM] ={0,0};
     uint16_t chargCurrent[THAISEN_MODULE_GROUP_NUM];
     switch(thaisenModuleGetStatusFun(gunNum))
      {
         case thaisenChargIdle:
             thaisenChangeModuleStatus(thaisenModuleIdle,gunNum);
             break;

          case thaisenChargCHM:
          case thaisenChargInsult:
          case thaisenChargInsultFinish:
          case thaisenChargCRM:
          case thaisenChargCTSCML:
          case thaisenChargCRO:
          case thaisenChargCROAA:
          case thaisenChargCST:
          case thaisenChargCSD:
          case thaisenChargStop:
          case thaisenChargWaitGun:
          case thaisenChargFault:
          case thaisenChargingFault:
          case thaisenChargCommonFault:
          case thaisenChargCommonEndFault:
              ModuleInfo[gunNum]->Elect.moduleOpenClose(1,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
              thaisenChangeModuleStatus(thaisenModuleChargStop,gunNum);
              break;
          case thaisenChargCCS:
              if(++cnt[gunNum] > 2)
              {
                 cnt[gunNum] = 0;

                 if(gunNum == 0)
                 {
                     if(thaisenModuleGetStatus(gunNum+1) == thaisenModuleChargParallel)
                     {
                         if((thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10/2 ) < (thaisenGetModuleMaxChargCurrGroup(gunNum) *10))
                         {
                             chargCurrent[gunNum] = thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10/2;
                         }
                         else
                         {
                             chargCurrent[gunNum] = thaisenGetModuleMaxChargCurrGroup(gunNum) *10;
                         }
                     }
                     else
                     {
                         if(thaisenModuleGetStatusFun(gunNum+1) == thaisenChargCCS)
                         {
                             if((thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10) < (thaisenGetModuleMaxChargCurrGroup(gunNum) *10))
                             {
                                 chargCurrent[gunNum] = thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10;
                             }
                             else
                             {
                                 chargCurrent[gunNum] = thaisenGetModuleMaxChargCurrGroup(gunNum) *10;
                             }
                         }
                         else
                         {
                            if((thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10) < ((thaisenGetModuleMaxChargCurrGroup(gunNum) + thaisenGetModuleMaxChargCurrGroup(gunNum + 1)) *10))
                            {
                                chargCurrent[gunNum] = thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10;
                            }
                            else
                            {
                                chargCurrent[gunNum] = ((thaisenGetModuleMaxChargCurrGroup(gunNum) + thaisenGetModuleMaxChargCurrGroup(gunNum + 1)) *10);
                            }
                         }
                     }


                     if (thaisenBMS_Add[gunNum]->BHM.MaxAllowVol < thaisenBMS_Add[gunNum]->BCL.BMSneedVolt) {
                         ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum]->BHM.MaxAllowVol,chargCurrent[gunNum],gunNum, thaisenModuleGetStatusFun(gunNum));
                     }
                     else {
                         ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum, thaisenModuleGetStatusFun(gunNum));
                    }
                 }
                 else  if(gunNum == 1)
                 {
                     if(thaisenModuleGetStatus(gunNum-1) == thaisenModuleChargParallel)
                     {
                         if((thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10/2 ) < (thaisenGetModuleMaxChargCurrGroup(gunNum) *10))
                         {
                             chargCurrent[gunNum] = thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt*10/2;
                         }
                         else
                         {
                             chargCurrent[gunNum] = thaisenGetModuleMaxChargCurrGroup(gunNum) *10;
                         }
                     }
                     else
                     {

                         if(thaisenModuleGetStatusFun(gunNum-1) == thaisenChargCCS)
                         {
                           if((thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10) < (thaisenGetModuleMaxChargCurrGroup(gunNum) *10))
                           {
                               chargCurrent[gunNum] = thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt*10;
                           }
                           else
                           {
                               chargCurrent[gunNum] = thaisenGetModuleMaxChargCurrGroup(gunNum) *10;
                           }
                         }
                         else
                         {
                               if((thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt *10) < ((thaisenGetModuleMaxChargCurrGroup(gunNum) + thaisenGetModuleMaxChargCurrGroup(gunNum - 1)) *10))
                               {
                                   chargCurrent[gunNum] = thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt*10;
//                                   rt_kprintf("111111111111111111111111111111111111111=%d,%d,%d,%d,%d,%d\r\n",gunNum,thaisenModuleGetStatusFun(gunNum-1),thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt,thaisenGetModuleMaxChargCurrGroup(gunNum),(thaisenGetModuleMaxChargCurrGroup(gunNum) + thaisenGetModuleMaxChargCurrGroup(gunNum - 1)),chargCurrent[gunNum]);
                               }
                               else
                               {
                                   chargCurrent[gunNum] = ((thaisenGetModuleMaxChargCurrGroup(gunNum) + thaisenGetModuleMaxChargCurrGroup(gunNum - 1)) *10);
//                                   rt_kprintf("222222222222222222222222222222222222=%d,%d,%d,%d,%d,%d\r\n",gunNum,thaisenModuleGetStatusFun(gunNum-1),thaisenBMS_Add[gunNum]->BCL.BMSneedCurlt,thaisenGetModuleMaxChargCurrGroup(gunNum),(thaisenGetModuleMaxChargCurrGroup(gunNum) + thaisenGetModuleMaxChargCurrGroup(gunNum - 1)),chargCurrent[gunNum]);
                               }
                        }
                     }
                     if(thaisenBMS_Add[gunNum]->BHM.MaxAllowVol < thaisenBMS_Add[gunNum]->BCL.BMSneedVolt){
                         ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum]->BHM.MaxAllowVol,chargCurrent[gunNum],gunNum, thaisenModuleGetStatusFun(gunNum));
                     }
                     else {
                         ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum, thaisenModuleGetStatusFun(gunNum));
                    }
                   }


                   ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
              }
              break;
      }
#if 0
     switch(gunNum)
     {
         case 0:
             if((thaisenModuleGetStatusFun(gunNum+1) == thaisenChargIdle) && (thaisenGetModuleGroupNum(gunNum+1) == THAISEN_MODULE_GROUP_NUM))
             {
                 thaisenChangeModuleStatus(thaisenModuleChargParallel,gunNum+1);
             }
             break;

         case 1:
             if((thaisenModuleGetStatusFun(gunNum-1) == thaisenChargIdle) && (thaisenGetModuleGroupNum(gunNum-1) == THAISEN_MODULE_GROUP_NUM))
             {
                 thaisenChangeModuleStatus(thaisenModuleChargParallel,gunNum-1);
             }
             break;
     }
#endif

/*
     switch(gunNum)
     {
         case 0:
             if(ModuleInfo[gunNum+1]->Elect.CC1_Status() == thaisenCC1_6v)
             {
                 thaisenChangeModuleStatus(thaisenModuleChargParallel,gunNum+1);
             }
             break;

         case 1:
             if(ModuleInfo[gunNum-1]->Elect.CC1_Status() == thaisenCC1_6v)
             {
                 thaisenChangeModuleStatus(thaisenModuleChargParallel,gunNum-1);
             }
             break;
     }
*/
}


void thaisenModuleChargStopFun(uint8_t gunNum)
{
    static uint16_t cnt[THAISEN_MODULE_GROUP_NUM] ={0,0};

    if(++cnt[gunNum] > 2)
     {
        cnt[gunNum] = 0;
        ModuleInfo[gunNum]->Elect.moduleOpenClose(1,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
     }

    if(ModuleInfo[gunNum]->Elect.moduleGetVolt(gunNum) < 600)
    {
        cnt[gunNum] = 0;
        thaisenChangeModuleStatus(thaisenModuleIdle,gunNum);
    }
}


void thaisenModuleChargParallelFun(uint8_t gunNum)
{
    static uint16_t cnt[THAISEN_MODULE_GROUP_NUM] ={0,0};
    static uint8_t delay_count[THAISEN_MODULE_GROUP_NUM]={0,0};
    static uint8_t run_one[THAISEN_MODULE_GROUP_NUM]={0,0};
    uint16_t chargCurrent[THAISEN_MODULE_GROUP_NUM];
    switch(gunNum)
    {
        case 0:
            if(++cnt[gunNum] > 2)
            {
                cnt[gunNum] = 0;
               if((thaisenBMS_Add[gunNum+1]->BCL.BMSneedCurlt *10/2 ) < (thaisenGetModuleMaxChargCurrGroup(gunNum+1) *10))
               {
                   chargCurrent[gunNum] = thaisenBMS_Add[gunNum+1]->BCL.BMSneedCurlt *10/2 ;
               }
               else
               {
                   chargCurrent[gunNum] = thaisenGetModuleMaxChargCurrGroup(gunNum+1) *10 ;
               }

               if(run_one[gunNum] == 0)
               {
                    if(++delay_count[gunNum] <= 5)
                    {
                        if(ModuleInfo[gunNum+1]->Elect.AmmeterVolt(gunNum+1)+50 > thaisenBMS_Add[gunNum+1]->BCL.BMSneedVolt)
                        {
                           ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum+1]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum,thaisenChargCRO);
                        }
                        else
                        {
                            ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(ModuleInfo[gunNum+1]->Elect.AmmeterVolt(gunNum+1)+50,chargCurrent[gunNum],gunNum,thaisenChargCRO);
                        }
                        ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum,thaisenChargCRO, thaisenBMS_Add[gunNum+1]->BCP.BatVolt);
                    }else{
                        delay_count[gunNum] = 5;
                        if(ModuleInfo[gunNum+1]->Elect.AmmeterVolt(gunNum+1)+50 > thaisenBMS_Add[gunNum+1]->BCL.BMSneedVolt)
                        {
                           ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum+1]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum+1));
                        }
                        else
                        {
                            ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(ModuleInfo[gunNum+1]->Elect.AmmeterVolt(gunNum+1)+50,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum+1));
                        }
                        ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum,thaisenModuleGetStatusFun(gunNum+1), thaisenBMS_Add[gunNum+1]->BCP.BatVolt);
                    }
               }
               else if(run_one[gunNum] == 1)
               {
                   delay_count[gunNum] = 0;
                   if(thaisenBMS_Add[gunNum+1]->BHM.MaxAllowVol < thaisenBMS_Add[gunNum+1]->BCL.BMSneedVolt){
                        ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum+1]->BHM.MaxAllowVol,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum+1));
                   }
                   else {
                        ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum+1]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum+1));
                   }
                   ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum,thaisenModuleGetStatusFun(gunNum+1), thaisenBMS_Add[gunNum+1]->BCP.BatVolt);
               }

                if(abs(ModuleInfo[gunNum+1]->Elect.moduleGetVolt(gunNum+1) - ModuleInfo[gunNum]->Elect.moduleGetVolt(gunNum)) < 200)
                {
                    if(run_one[gunNum] == 0)
                    {
                        delay_count[gunNum] = 0;
                        run_one[gunNum] = 1;
                        ModuleInfo[gunNum]->Elect.parallelZRelayEnable();
                        ModuleInfo[gunNum]->Elect.parallelFRelayEnable();
                    }
                }

                if(thaisenModuleGetStatusFun(gunNum) != thaisenChargIdle || thaisenModuleGetStatus(gunNum+1) != thaisenModuleChargCCS)
                {
                    run_one[gunNum] = 0;
                    delay_count[gunNum] = 0;
                    thaisenChangeModuleStatus(thaisenModuleChargParallelDischarg,gunNum);
                }


    /*
                if(ModuleInfo[gunNum]->Elect.CC1_Status() == thaisenCC1_4v || thaisenModuleGetStatus(gunNum+1) != thaisenModuleChargCCS)
                {
                    run_one[gunNum] = 0;
                    thaisenChangeModuleStatus(thaisenModuleChargParallelDischarg,gunNum);
                }
    */
            }
            break;

        case 1:
            if(++cnt[gunNum] > 2)
            {
                cnt[gunNum] = 0;
                if((thaisenBMS_Add[gunNum-1]->BCL.BMSneedCurlt *10/2) < (thaisenGetModuleMaxChargCurrGroup(gunNum-1) *10))
                {
                    chargCurrent[gunNum] = thaisenBMS_Add[gunNum-1]->BCL.BMSneedCurlt *10/2;
                }
                else
                {
                    chargCurrent[gunNum] = thaisenGetModuleMaxChargCurrGroup(gunNum-1) *10;
                }

                if(run_one[gunNum] == 0)
                {
                    if(++delay_count[gunNum] <= 5)
                    {
                        if(ModuleInfo[gunNum-1]->Elect.AmmeterVolt(gunNum-1)+50 > thaisenBMS_Add[gunNum-1]->BCL.BMSneedVolt)
                        {
                           ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum-1]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum,thaisenChargCRO);
                        }
                        else
                        {
                            ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(ModuleInfo[gunNum-1]->Elect.AmmeterVolt(gunNum-1)+50,chargCurrent[gunNum],gunNum,thaisenChargCRO);
                        }
                        ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum,thaisenChargCRO, thaisenBMS_Add[gunNum-1]->BCP.BatVolt);
                    }
                    else
                    {
                        delay_count[gunNum] = 5;
                        if(ModuleInfo[gunNum-1]->Elect.AmmeterVolt(gunNum-1)+50 > thaisenBMS_Add[gunNum-1]->BCL.BMSneedVolt)
                        {
                           ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum-1]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum-1));
                        }
                        else
                        {
                            ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(ModuleInfo[gunNum-1]->Elect.AmmeterVolt(gunNum-1)+50,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum-1));
                        }
                        ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum,thaisenModuleGetStatusFun(gunNum-1), thaisenBMS_Add[gunNum-1]->BCP.BatVolt);
                    }
                }
                else if(run_one[gunNum] == 1)
                {
                    delay_count[gunNum] = 0;
                    if(thaisenBMS_Add[gunNum-1]->BHM.MaxAllowVol < thaisenBMS_Add[gunNum-1]->BCL.BMSneedVolt){
                         ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum-1]->BHM.MaxAllowVol,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum-1));
                     }
                     else {
                         ModuleInfo[gunNum]->Elect.moduleSetVoltCurr(thaisenBMS_Add[gunNum-1]->BCL.BMSneedVolt,chargCurrent[gunNum],gunNum,thaisenModuleGetStatusFun(gunNum-1));
                     }
                    ModuleInfo[gunNum]->Elect.moduleOpenClose(0,gunNum,thaisenModuleGetStatusFun(gunNum-1), thaisenBMS_Add[gunNum-1]->BCP.BatVolt);
                }

                if(abs(ModuleInfo[gunNum]->Elect.moduleGetVolt(gunNum) - ModuleInfo[gunNum-1]->Elect.moduleGetVolt(gunNum-1)) < 200)
                {
                    if(run_one[gunNum] == 0)
                    {
                        delay_count[gunNum] = 0;
                        run_one[gunNum] = 1;
                        ModuleInfo[gunNum]->Elect.parallelZRelayEnable();
                        ModuleInfo[gunNum]->Elect.parallelFRelayEnable();
                    }
                }
               if(thaisenModuleGetStatusFun(gunNum) != thaisenChargIdle || thaisenModuleGetStatus(gunNum-1) != thaisenModuleChargCCS)
               {
                   delay_count[gunNum] = 0;
                   run_one[gunNum] = 0;
                   thaisenChangeModuleStatus(thaisenModuleChargParallelDischarg,gunNum);
               }
    /*
                if(ModuleInfo[gunNum]->Elect.CC1_Status() == thaisenCC1_4v || thaisenModuleGetStatus(gunNum-1) != thaisenModuleChargCCS)
                {
                    run_one[gunNum] = 0;
                    thaisenChangeModuleStatus(thaisenModuleChargParallelDischarg,gunNum);
                }
    */
            }
            break;
    }
}

void thaisenModuleChargParallelDischarglFun(uint8_t gunNum)
{
    static uint16_t cnt[THAISEN_MODULE_GROUP_NUM] ={0,0};

     if(++cnt[gunNum] > 2)
      {
         cnt[gunNum] = 0;
         ModuleInfo[gunNum]->Elect.moduleOpenClose(1,gunNum, thaisenModuleGetStatusFun(gunNum), thaisenBMS_Add[gunNum]->BCP.BatVolt);
      }

     if(ModuleInfo[gunNum]->Elect.moduleGetVolt(gunNum) < 600)
     {
         cnt[gunNum] = 0;
         ModuleInfo[gunNum]->Elect.parallelZRelayClose();
         ModuleInfo[gunNum]->Elect.parallelFRelayClose();
         thaisenChangeModuleStatus(thaisenModuleIdle,gunNum);
     }
}

void thaisenModuleFaultFun(uint8_t gunNum)
{

}


typedef void (*thaisenModuleFun)(uint8_t);
thaisenModuleFun thaisenModuleTaskList[thaisenModuleAll] =
{
    thaisenModuleIdleFun,
    thaisenModuleChargInsultFun,
    thaisenModuleChargCROFun,
    thaisenModuleChargCCSFun,
    thaisenModuleChargStopFun,
    thaisenModuleChargParallelFun,
    thaisenModuleChargParallelDischarglFun,
    thaisenModuleFaultFun,
};

thaisenModuleFun thaisenModuleFunP[THAISEN_MODULE_GROUP_NUM];

void thaisenChangeModuleStatus(thaisenModuleStatusEn status,uint8_t gunNum)
{
    thaisenModuleFunP[gunNum] = thaisenModuleTaskList[status];//充电模块状态
    thaisenModuleStatus[gunNum] = status;//标志位
}

uint8_t thaisenModuleGetStatus(uint8_t gunNum)
{
    return thaisenModuleStatus[gunNum];
}
/* 判断模块状态(用于设置故障) */
void thaisenModuleFaultCheck(void)
{
    uint8_t fault_count[THAISEN_MODULE_GROUP_NUM][VALID_FAULT_NUMBER];//错误 计数
    uint8_t abnormal_number[THAISEN_MODULE_GROUP_NUM], remain = 0;//非正常模块数量
    thaisenModuleGeneralFaultStruct *state;/* 通用模块故障 */
    uint8_t count = 0, group = 0, number = 0, ac_relay_state = thaisen_relay_AC_SetFB();//交流接触器状态

    for(count = 0; count < THAISEN_MODULE_GROUP_NUM; count++){
        abnormal_number[count] = 0;//非正常模块数量置0
    }
    for(group = 0; group < THAISEN_MODULE_GROUP_NUM; group++){
        number = thaisenGetModuleGunNum(group);//****************这个没有赋值
//        rt_kprintf("--5_-%d---\r\n",number);
        abnormal_number[group] = 0;
        remain = 0;
        for(count = 0; count < VALID_FAULT_NUMBER; count++){//有效模块数量3
            fault_count[group][count] = 0;
        }
//        for(count = 0; count < number; count++){
            count = 0;
            state = (thaisenModuleGeneralFaultStruct*)((ModuleInfo[group]->Elect.getModuleState(group, count)));//获取模块状态
//            rt_kprintf("--4_-%d---\r\n",count);
//            rt_kprintf("--6_-%d---\r\n",state->fault.ModuleFault);
            if(state->fault.fault_val != 0){
                abnormal_number[group]++;//若故障的值不为0，故障计数加一
                if(!(state->fault.ModuleFault)){//若模块没有故障
                    if(state->fault.InputOverVolt){//输出过压故障
                        fault_count[group][INPUT_OVERVOLT_FAULT_COUNT_INDEX]++;//过压故障++
                    }
                    if(state->fault.InputUnderVolt){
                        fault_count[group][INPUT_UNDERVOLT_FAULT_COUNT_INDEX]++;
                    }
                    if(state->fault.OverCurr){
                        fault_count[group][OVERCURR_FAULT_COUNT_INDEX]++;
                    }
                }
            }
//        }

        if(abnormal_number[group] <= thaisenGetModuleNum(group)){//若非正常模块数量小于模块数量
            remain = (thaisenGetModuleNum(group) - abnormal_number[group]);//剩余模块数量
        }
        if(remain != thaisenGetNormalModuleNum(group)){
            thaisenSetNormalModuleNum(remain, group);//若剩余模块数量不等于正常模块数量，设置正常模块数量为剩余模块数量
        }
        if(abnormal_number[group] >= thaisenGetModuleNum(group)){   /* 该组所有模块都有故障 *///输入过电压故障计数等于该组的模块数量，并且该组的模块数量不为零，则条件为真
            if((fault_count[group][INPUT_OVERVOLT_FAULT_COUNT_INDEX] == thaisenGetModuleNum(group)) && (thaisenGetModuleNum(group) != 0)){
                if(++fault_detect_delay[group][INPUT_OVERVOLT_FAULT_COUNT_INDEX] >= 7 *1000 /50){   /* 时机为50ms */
                    fault_detect_delay[group][INPUT_OVERVOLT_FAULT_COUNT_INDEX] = 7 *1000 /50;//过压故障7S
                    if((ac_relay_state == thaisenRelayClose)){
                        thaisenSetSysFaultLib(thaisenFaultOverVolt,group);//设置为过压故障
                    }else{
                        thaisenClearSysFaultLib(thaisenFaultOverVolt, group);
                        fault_detect_delay[group][INPUT_OVERVOLT_FAULT_COUNT_INDEX] = 0;
                    }
                }
            }else{
                fault_detect_delay[group][INPUT_OVERVOLT_FAULT_COUNT_INDEX] = 0;
                thaisenClearSysFaultLib(thaisenFaultOverVolt, group);
            }

            if((fault_count[group][INPUT_UNDERVOLT_FAULT_COUNT_INDEX] == thaisenGetModuleNum(group)) && (thaisenGetModuleNum(group) != 0)){
                if(++fault_detect_delay[group][INPUT_UNDERVOLT_FAULT_COUNT_INDEX] >= 7 *1000 /50){   /* 时机为50ms */
                    fault_detect_delay[group][INPUT_UNDERVOLT_FAULT_COUNT_INDEX] = 7 *1000 /50;
                    if((ac_relay_state == thaisenRelayClose)){
                        thaisenSetSysFaultLib(thaisenFaultUnderVolt,group);
                    }else{
                        thaisenClearSysFaultLib(thaisenFaultUnderVolt, group);
                        fault_detect_delay[group][INPUT_UNDERVOLT_FAULT_COUNT_INDEX] = 0;//欠压
                    }
                }
            }else{
                fault_detect_delay[group][INPUT_UNDERVOLT_FAULT_COUNT_INDEX] = 0;
                thaisenClearSysFaultLib(thaisenFaultUnderVolt, group);
            }

            if((fault_count[group][OVERCURR_FAULT_COUNT_INDEX] == thaisenGetModuleNum(group)) && (thaisenGetModuleNum(group) != 0)){
                if(++fault_detect_delay[group][OVERCURR_FAULT_COUNT_INDEX] >= 7 *1000 /50){   /* 时机为50ms */
                    fault_detect_delay[group][OVERCURR_FAULT_COUNT_INDEX] = 7 *1000 /50;
                    if((ac_relay_state == thaisenRelayClose)){
                        thaisenSetSysFaultLib(thaisenFaultOverCurrent,group);
                    }else{
                        thaisenClearSysFaultLib(thaisenFaultOverCurrent, group);
                        fault_detect_delay[group][OVERCURR_FAULT_COUNT_INDEX] = 0;//过流
                    }
                }
            }else{
                fault_detect_delay[group][OVERCURR_FAULT_COUNT_INDEX] = 0;
                thaisenClearSysFaultLib(thaisenFaultOverCurrent, group);
            }
        }else{
            fault_detect_delay[group][INPUT_OVERVOLT_FAULT_COUNT_INDEX] = 0;
            fault_detect_delay[group][INPUT_UNDERVOLT_FAULT_COUNT_INDEX] = 0;
            fault_detect_delay[group][OVERCURR_FAULT_COUNT_INDEX] = 0;

            thaisenClearSysFaultLib(thaisenFaultOverCurrent, group);
            thaisenClearSysFaultLib(thaisenFaultUnderVolt, group);
            thaisenClearSysFaultLib(thaisenFaultOverVolt, group);
        }
    }
}
/*****************
 * 模块的任务
 * @param gunNum
 */
void thaisenModuleTask(uint8_t gunNum)
{
    static uint8_t run_one[THAISEN_MODULE_GROUP_NUM]={0,0};

    if(run_one[gunNum] == 0)
    {
        ModuleInfo[gunNum]->Elect.moduleInit(PowerInfoSetInfo);//进入调试模式
        thaisenChangeModuleStatus(thaisenModuleIdle,gunNum);//获取模块状态
        run_one[gunNum] = 1;//run_one置1
    }
    thaisenModuleFunP[gunNum](gunNum);//thaisenModuleFunP[gunNum]函数，gunNum参数
//	if(thaisen_get_SentErrCnt(gunNum) > 5)//模块通讯故障发送计数大于5
//	{
//		ModuleInfo[gunNum]->Alrm[MODULE_ERR_COMM].status = thaisenChargModuleOffLine;//模块离线告警
//		thaisenSetSysFaultLib(thaisenChargModule,gunNum);//设置系统故障模块故障
//	}
//	else
//	{
//        thaisenClearSysFaultLib(thaisenChargModule,gunNum);//若不大于5，清除系统故障
//        ModuleInfo[gunNum]->Alrm[MODULE_ERR_COMM].status = thaisenChargModuleOnLine;//status=0在线
//	}
}
//thaisenModuleGetStatusFun(gunNum);liquid_count

static void thaisen_chargModuleTx_thread_entry(void *parameter)
{
#if 1
    struct charge_data *chargeInfocontrol[THAISEN_MODULE_GROUP_NUM];
    static uint8_t cnt_tick[8];
//    static uint8_t count_gun[THAISEN_MODULE_GROUP_NUM][3];//两组，一组3个模块
    static thaisenRelayEn mpower_curr = thaisenRelayClose, mpower_last = thaisenRelayClose;//交流接触器闭合
    while(1)
    {

        if(++cnt_tick[4]>=20)//1s后
        {
            cnt_tick[4] = 0;
            rt_kprintf("ModuleGetStatus = %d,%d\r\n", thaisenModuleGetStatus(0), thaisenModuleGetStatus(1));//打印当前任务
        }


        if(thaisen_get_debug_mode() == thaisen_debug_mode_exit)//如果退出调试模式
        {
            thaisenModuleTask(THAISE_MODULE_GROUP_1);
            thaisenModuleTask(THAISE_MODULE_GROUP_2);
        }
//        else if(thaisen_get_debug_mode() == thaisen_debug_mode_enter)//进入调试模式
//        {
//            if(++cnt_tick[1]>=40)//大于2s
//            {
//               cnt_tick[1] = 0;
//               if(cnt_tick[2] < 10)//0.5s内
//               {
//                   cnt_tick[2]++;
//                   ModuleInfo[0]->Elect.moduleAddress();
//                   ModuleInfo[0]->Elect.moduleGroup();//获取模块的地址组数
//               }
//            }
//            mpower_curr = thaisen_relay_AC_SetFB();//交流接触器的反馈给mpower_curr
//            if(mpower_curr != mpower_last){
//                if(mpower_last == thaisenRelayBreak){//mpower_last=1，mpower_curr=0
//                    cnt_tick[1] = 40;//500ms获取一次组数
//                    cnt_tick[2] = 0;
//                    rt_kprintf("ac relay close, reset cnt count then set addr and group\n");
//                }
//                mpower_last = mpower_curr;
//            }
//            if(++cnt_tick[5] > 40){
//                cnt_tick[5] = 0;
////                ModuleInfo[0]->Elect.moduleHeart(0);//2000ms一次心跳
//            }
//        }

        if(thaisen_relay_AC_SetFB() == thaisenRelayClose)//若交流接触器闭合
        {
            if(++cnt_tick[0]>=20)//1000ms
            {
                 ModuleInfo[0]->Elect.moduleReadVoltCurr(0);//读模块电压电流
                 ModuleInfo[0]->Data.SentErrCnt++;
                 ModuleInfo[1]->Elect.moduleReadVoltCurr(1);
                 ModuleInfo[1]->Data.SentErrCnt++;//通信故障计数加一
               cnt_tick[0] = 0;
            }

            if(++cnt_tick[1]>=40)
            {
               cnt_tick[1] = 0;
               if(cnt_tick[2] < 10)
               {
                   cnt_tick[2]++;
                   ModuleInfo[0]->Elect.moduleAddress();
                   ModuleInfo[0]->Elect.moduleGroup();
               }
            }
        }
        else
        {//若交流接触器没有闭合
            cnt_tick[0] = 0;
            if(thaisen_get_debug_mode() == thaisen_debug_mode_exit)
            {
                cnt_tick[1] = 0;
                cnt_tick[2] = 0;
            }

            for(uint8_t gunNum = 0; gunNum < THAISEN_MODULE_GROUP_NUM; gunNum++)
            {
                if(thaisenGetModuleDebugEnableOutput(gunNum) == 0)//若模块不在使能状态
                {
                    ModuleInfo[gunNum]->Data.SentErrCnt = 0;
                }
            }
        }

        if(++cnt_tick[3]>=25)//750ms读模块状态
        {
            ModuleInfo[0]->Elect.moduleReadState(0);
            ModuleInfo[1]->Elect.moduleReadState(1);
            cnt_tick[3] = 0;
        }

        if(++cnt_tick[7] > 20)
        {
            cnt_tick[7] = 0;
            ModuleInfo[0]->Elect.set_terminal_status(0,(thaisen_get_CC1_status()-1),thaisenGettemminalscramStatus(),thaisenGettemminalDoorStatus(),0);//1000ms一次发送一次状态
            ModuleInfo[1]->Elect.set_terminal_status(1,(thaisen_get_CC1_statusB()-1),thaisenGettemminalscramStatus(),thaisenGettemminalDoorStatus(),0);
            ModuleInfo[0]->Elect.set_terminal_data(0,thaisen_get_ammeterVolt(0),thaisen_get_ammeterCurrent(0),thaisen_get_ammeterVolt(0)*thaisen_get_ammeterCurrent(0),chargeInfocontrol[0]->charge_time/3600);//1000ms一次发送一次数据
            ModuleInfo[1]->Elect.set_terminal_data(1,thaisen_get_ammeterVolt(1),thaisen_get_ammeterCurrent(1),thaisen_get_ammeterVolt(1)*thaisen_get_ammeterCurrent(1),chargeInfocontrol[1]->charge_time/3600);
        }
        if(++cnt_tick[5] > 40)
        {
            cnt_tick[5] = 0;
            ModuleInfo[0]->Elect.moduleHeart(0);//2000ms一次心跳
            ModuleInfo[1]->Elect.moduleHeart(1);//2000ms一次心跳
        }
        for(uint8_t gunNum = 0; gunNum < THAISEN_MODULE_GROUP_NUM; gunNum++)
        {
            if((thaisenModuleGetStatusFun(gunNum) >= thaisenChargStop) || (thaisenModuleGetStatusFun(gunNum) == 0))/*停止及空闲状态*/
            {
                if(thaisen_get_debug_mode() == thaisen_debug_mode_exit)/*不在出厂调试模式*/
                {
//                    liquid_count = 0;
//                }
//                else
//                {
                    if(++liquid_count >= 6000)
                    {
                        thaisenSetLiquidStop(gunNum);
                    }
                }

            }
        }

        /* 判断模块状态(用于设置故障) */
        thaisenModuleFaultCheck();
        rt_thread_mdelay(50);
    }
#endif
}


uint16_t thaisen_get_SentErrCnt(uint8_t gunNum)
{	
    if(PowerInfoSetInfo->gunNumber <= gunNum)
        return 0;

	return ModuleInfo[gunNum]->Data.SentErrCnt;
}

void thaisen_clear_SentErrCnt(uint8_t gunNum)
{
    if(PowerInfoSetInfo->gunNumber <= gunNum)
        return ;

	ModuleInfo[gunNum]->Data.SentErrCnt = 0;
}



static void thaisen_chargModuleQueueRx_thread_entry(void *parameter)
{
    can_msg_buf rx_buf;
    while(1)
    {
        if (rt_mq_recv(&thaisenModuleMq, &rx_buf, sizeof(can_msg_buf), RT_WAITING_FOREVER) == RT_EOK)
        {
//            if((PowerInfoSetInfo->moduleProNo == thaisenModuleProYouYou) && (rx_buf.data[1] == 0x5F)){
//                rt_thread_mdelay(1000);
//            }
           thaisen_chargmodule_can_send(&rx_buf);
        }
        rt_thread_mdelay(5);
    }
}



static struct rt_thread thaisenChargModuleThread;//线程控制块
static rt_uint8_t rt_thaisenChargModule_stack[2048];//线程栈


static struct rt_thread thaisenChargModuleQueueRxThread;//线程控制块
static rt_uint8_t rt_thaisenChargModuleQueueRx_stack[2048];//线程栈

/**************
 * 充电模块线程一个接收
 * 一个发送
 *
 *
 * @return
 *************/
int thaisen_chargModule_device_init(void)
{
    rt_err_t ret = RT_EOK;
    // 创建静态线程
       rt_thread_init(&thaisenChargModuleThread,           //线程控制块
                      "th_chargModule_tx",                       //线程名字，在shell里面可以看到
                      thaisen_chargModuleTx_thread_entry,       //线程入口函数
                      RT_NULL,                            //线程入口函数参数
                      &rt_thaisenChargModule_stack[0],      //线程栈起始地址
                      sizeof(rt_thaisenChargModule_stack),  //线程栈大小
                      9,                                  //线程的优先级
                      10);                                //线程时间片

       rt_thread_startup(&thaisenChargModuleThread);             //启动线程hlw_thread，开启调度


       // 创建静态线程
          rt_thread_init(&thaisenChargModuleQueueRxThread,           //线程控制块
                         "th_ModuleQueue_rx",                       //线程名字，在shell里面可以看到
                         thaisen_chargModuleQueueRx_thread_entry,       //线程入口函数
                         RT_NULL,                            //线程入口函数参数
                         &rt_thaisenChargModuleQueueRx_stack[0],      //线程栈起始地址
                         sizeof(rt_thaisenChargModuleQueueRx_stack),  //线程栈大小
                         10,                                  //线程的优先级
                         10);                                //线程时间片

          rt_thread_startup(&thaisenChargModuleQueueRxThread);             //启动线程hlw_thread，开启调度


    return ret;
}


thaisenModuleGetStatusFun_p  thaisenModuleGetStatusFun;
struct thaisenBMS_Charger_struct *thaisenBMS_Add[THAISEN_GUN_NUM];


//模块初始化，获取现在任务的状态
void thaisen_chargpowercontrol_Init(thaisenModuleGetStatusFun_p getStaFun,struct thaisenBMS_Charger_struct *chargerA,struct thaisenBMS_Charger_struct *chargerB,struct thasienPowerControlSetStruct *powerS )
{
    thaisenModuleGetStatusFun = getStaFun;//获取此刻的状态是在什么阶段
    thaisenBMS_Add[0] =chargerA;
    thaisenBMS_Add[1] =chargerB;//把与车通信的数据传入,,BSM
    thaisenModuleInit(powerS);//功率控制板初始化
    thaisen_chargModule_device_init();//模块线程的初始化



//    for(uint16_t i = 0;i < THAISEN_MODULE_GROUP_NUM;i++)
//    {
//        thaisenSetModuleGroupNum(moduleS->moduleGroupNum,i);//设置模块组数
//        thaisenSetModuleNum(moduleS->moduleSingleGroupNum[i],i);//设置组内个数
//        thaisenSetNormalModuleNum(moduleS->moduleSingleGroupNum[i],i);//设置正常模块数量，就是设置的正常模块数量
//    }

    memset(&fault_detect_delay[0][0], 0x00, sizeof(fault_detect_delay));

    LOG_W("libChargModule_7102.a <v1.0.6> <20240103>");
}

static thaisenDebugEn thaisenDebugModeStatus[2];
/************************
 * 设置调试状态标志
 * @param status
 */
void thaisen_set_chargModule_debug_modeA(thaisenDebugEn status)
{
    thaisenDebugModeStatus[0] = status;
}


uint8_t thaisen_get_chargModule_debug_modeA(void)
{
    return thaisenDebugModeStatus[0];
}


void thaisen_set_chargModule_debug_modeB(thaisenDebugEn status)
{
    thaisenDebugModeStatus[1] = status;
}


uint8_t thaisen_get_chargModule_debug_modeB(void)
{
    return thaisenDebugModeStatus[1];
}



uint32_t thaisen_get_module_volt(uint8_t gunNum)
{
    rt_kprintf("thaisen_get_module_volt(%d, %d, %d)\n", gunNum, PowerInfoSetInfo->gunNumber, ModuleInfo[gunNum]->Elect.moduleGetVolt(gunNum));
//    if(PowerInfoSetInfo->gunNumber <= gunNum)
//       return 0;

	return ModuleInfo[gunNum]->Elect.moduleGetVolt(gunNum);
}

uint16_t  thaisenModuleGetStatusFun1(uint8_t cmd)
{
    return 0;
}

/***************
 * 接收数据的函数就是在这个回调函数中调用
 */
void thaisen_user_chargModule_isrCallback(void)
{	
	if(ModuleInfo[0]->Elect.chargModuleProcess != NULL)//为什么不等于NUll呢，本来接没有返回值，因为函数只有在未初始化时才等于NULL
		ModuleInfo[0]->Elect.chargModuleProcess();
	else 
	{

	}

}


/******
 * 返回模块的普通故障
 * @param gunNum
 * @return
 */
thaisenChargModuleEn thaisenGetChargModuleCommErr(uint8_t gunNum)
{
    if(PowerInfoSetInfo->gunNumber <= gunNum)
       return 0;
	return ModuleInfo[gunNum]->Alrm[MODULE_ERR_COMM].status;
}





